package com.leoman.plz_p.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;

import cn.com.corelib.utils.ToastMgr;


/**
 * Created by guoh on 2017/2/28.
 */

public class FileUtils{

    public static final String IMAGE_CACHE_FOLDER = "ImageUploaderCache";
    public static final String IMAGE_BASE_NAME = "tmp";
    public static final String IMAGE_BASE_TYPE = ".jpeg";
    public static final int IMAGE_MAX_SIZE = 1080;

    //加 . 之后为系统隐藏文件 用户将无法看到该文件夹
    private final static String DOWNLOAD_DIR="download";

    private final static String ROOT_DIR="com.bm.demo";

    private final static String SEPARATOR = File.separator;


    public enum sizeType{
        B,
        KB,
        MB,
        GB
    }

    /**
     * create folder
     * @param dir
     * @return
     */
    private static boolean createDir(String dir){
        File desDir = new File(dir);
        if(!desDir.exists()){
            boolean mkStatus = desDir.mkdirs();
            if(mkStatus){
                return true;
            }
            return false;
        }
        return true;
    }

    public static File bitmapToFile(Context context, Bitmap bmp) throws IOException {
        return bitmapToFile(context, bmp, Bitmap.CompressFormat.JPEG);
    }

    public static File bitmapToFile(Context context, Bitmap bmp, Bitmap.CompressFormat format)
            throws IOException {
        String imageCachePath = context.getExternalCacheDir() + File.separator + IMAGE_CACHE_FOLDER;
        String filename = File.separator + IMAGE_BASE_NAME + System.currentTimeMillis() + IMAGE_BASE_TYPE;
        File file = new File(imageCachePath + filename);
        if (!file.exists()) {
            File dir = new File(imageCachePath);
            if (!dir.exists()) {
                if (!dir.mkdirs()) ToastMgr.show("创建图片缓存文件夹失败");
            }
            if (!file.createNewFile()) ToastMgr.show("创建图片文件失败");
        }
        int quality = 100;
        OutputStream stream = null;
        try {
            stream = new FileOutputStream(imageCachePath + filename);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        boolean result = bmp.compress(format, quality, stream);

        if (result) {
            bmp.recycle();
            return file;
        }

        return null;
    }


    public static File compressFile(Context context, String filePath) {
        try {
            return bitmapToFile(context,
                    compressBitmap(BitmapFactory.decodeFile(filePath)));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static Bitmap compressBitmap(Bitmap bitmap) {
        return compressBitmap(bitmap, IMAGE_MAX_SIZE);
    }

    public static Bitmap compressBitmap(Bitmap bitmap, int maxSize) {
        int mWidth = bitmap.getWidth();
        int mHeight = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleW;
        float scaleH;
        if (mWidth <= mHeight) {
            scaleH = maxSize / (float) mHeight;
            scaleW = scaleH;
        } else {
            scaleW = maxSize / (float) mWidth;
            scaleH = scaleW;
        }
        matrix.postScale(scaleW, scaleH);
        Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, mWidth, mHeight, matrix, true);

        if(newBitmap != bitmap)
            bitmap.recycle();
        return newBitmap;
    }

    /**
     * 获取根目录
     * @return
     */
    private static File getRootDir(){
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);
        File rootFile = null;
        if(sdCardExist)
            rootFile= Environment.getExternalStorageDirectory();
        return rootFile;
    }

    /**
     * 初始化
     * @param
     */
    public static void initDir(){
        File root=getRootDir();
        if (root!=null){
            createDownloadMediaDir();
        }

    }

    private static boolean createDownloadMediaDir(){
        return createDir(getMediaPath());
    }

    public static String getMediaPath(){
        String mediaPath =getRootPath() + SEPARATOR + (DOWNLOAD_DIR);
        return mediaPath;
    }

    /**
     * 返回根目录
     * @return
     */
    public static String getRootPath(){
        String rootPath = getRootDir() + SEPARATOR + ROOT_DIR;
        return rootPath;
    }

    /**
     * 删除单个文件
     * @param   filePath    被删除文件的文件名
     * @return 文件删除成功返回true，否则返回false
     */
    private static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 删除文件夹以及目录下的文件
     * @param   filePath 被删除目录的文件路径
     * @return  目录删除成功返回true，否则返回false
     */
    private static boolean deleteDirectory(String filePath) {
        boolean flag = false;
        //如果filePath不以文件分隔符结尾，自动添加文件分隔符
        if (!filePath.endsWith(File.separator)) {
            filePath = filePath + File.separator;
        }
        File dirFile = new File(filePath);
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        flag = true;
        File[] files = dirFile.listFiles();
        //遍历删除文件夹下的所有文件(包括子目录)
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                //删除子文件
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) break;
            } else {
                //删除子目录
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) break;
            }
        }
        if (!flag) return false;
        //删除当前空目录
        return dirFile.delete();
    }

    /**
     *  根据路径删除指定的目录或文件，无论存在与否
     *@param filePath  要删除的目录或文件
     *@return 删除成功返回 true，否则返回 false。
     */
    public static boolean deleteFolder(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return false;
        } else {
            if (file.isFile()) {
                // 为文件时调用删除文件方法
                return deleteFile(filePath);
            } else {
                // 为目录时调用删除目录方法
                return deleteDirectory(filePath);
            }
        }
    }

    /**
     * 获取文件指定文件的指定单位的大小
     *
     * @param filePath
     *            文件路径
     * @param sizeType
     *            获取大小的类型1为B、2为KB、3为MB、4为GB
     * @return double值的大小
     */
    public static double getFileOrFilesSize(String filePath, sizeType sizeType) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("获取文件大小", "获取失败!");
        }
        return FormatFileSize(blockSize, sizeType);
    }
    /**
     * 调用此方法自动计算指定文件或指定文件夹的大小
     *
     * @param filePath
     *            文件路径
     * @return 计算好的带B、KB、MB、GB的字符串
     */
    public static String getAutoFileOrFilesSize(String filePath) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("获取文件大小", "获取失败!");
        }
        return FormetFileSize(blockSize);
    }
    /**
     * 获取指定文件大小
     *
     * @param
     * @return
     * @throws Exception
     */
    private static long getFileSize(File file) throws Exception {
        long size = 0;
        if (file.exists()) {
            FileInputStream fis = null;
            fis = new FileInputStream(file);
            size = fis.available();
        } else {
            file.createNewFile();
            Log.e("获取文件大小", "文件不存在!");
        }
        return size;
    }
    /**
     * 获取指定文件夹
     *
     * @param f
     * @return
     * @throws Exception
     */
    private static long getFileSizes(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSizes(flist[i]);
            } else {
                size = size + getFileSize(flist[i]);
            }
        }
        return size;
    }
    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    public static String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "(0B)";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return ""+fileSizeString+"";
    }
    /**
     * 转换文件大小,指定转换的类型
     *
     * @param fileS
     * @param sizeType
     * @return
     */
    private static double FormatFileSize(long fileS, sizeType sizeType) {
        DecimalFormat df = new DecimalFormat("#.00");
        double fileSizeLong = 0;
        switch (sizeType) {
            case B:
                fileSizeLong = Double.valueOf(df.format((double) fileS));
                break;
            case KB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
                break;
            case MB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
                break;
            case GB:
                fileSizeLong = Double.valueOf(df
                        .format((double) fileS / 1073741824));
                break;
            default:
                break;
        }
        return fileSizeLong;
    }
}
